classicube_sys\vectors\matrix/
mod.rs

1mod ops;
2
3use crate::{
4    bindings::*,
5    std_types::{c_double, c_float},
6    Tan_Simple,
7};
8
9impl Matrix {
10    pub const IDENTITY: Self = Matrix_IdentityValue();
11
12    pub const fn identity_value() -> Self {
13        Matrix_IdentityValue()
14    }
15
16    /// Returns a matrix representing a counter-clockwise rotation around x axis.
17    pub fn rotate_x(angle: c_float) -> Self {
18        let mut result = Self::IDENTITY;
19        unsafe {
20            Matrix_RotateX(&mut result, angle);
21        }
22        result
23    }
24
25    /// Returns a matrix representing a counter-clockwise rotation around y axis.
26    pub fn rotate_y(angle: c_float) -> Self {
27        let mut result = Self::IDENTITY;
28        unsafe {
29            Matrix_RotateY(&mut result, angle);
30        }
31        result
32    }
33
34    /// Returns a matrix representing a counter-clockwise rotation around z axis.
35    pub fn rotate_z(angle: c_float) -> Self {
36        let mut result = Self::IDENTITY;
37        unsafe {
38            Matrix_RotateZ(&mut result, angle);
39        }
40        result
41    }
42
43    /// Returns a matrix representing a translation to the given coordinates.
44    pub fn translate(x: c_float, y: c_float, z: c_float) -> Self {
45        let mut result = Self::IDENTITY;
46        unsafe {
47            Matrix_Translate(&mut result, x, y, z);
48        }
49        result
50    }
51
52    /// Returns a matrix representing a scaling by the given factors.
53    pub fn scale(x: c_float, y: c_float, z: c_float) -> Self {
54        let mut result = Self::IDENTITY;
55        unsafe {
56            Matrix_Scale(&mut result, x, y, z);
57        }
58        result
59    }
60
61    pub fn orthographic(
62        left: c_float,
63        right: c_float,
64        top: c_float,
65        bottom: c_float,
66        zNear: c_float,
67        zFar: c_float,
68    ) -> Self {
69        let mut result = Self::IDENTITY;
70        Matrix_Orthographic(&mut result, left, right, top, bottom, zNear, zFar);
71        result
72    }
73
74    pub fn perspective_field_of_view(
75        fovy: c_float,
76        aspect: c_float,
77        z_near: c_float,
78        z_far: c_float,
79    ) -> Self {
80        let mut result = Self::IDENTITY;
81        Matrix_PerspectiveFieldOfView(&mut result, fovy, aspect, z_near, z_far);
82        result
83    }
84
85    pub fn look_rot(pos: Vec3, rot: Vec2) -> Self {
86        let mut result = Self::IDENTITY;
87        Matrix_LookRot(&mut result, pos, rot);
88        result
89    }
90}
91
92pub const fn Matrix_IdentityValue() -> Matrix {
93    Matrix {
94        row1: Vec4 {
95            x: 1.0,
96            y: 0.0,
97            z: 0.0,
98            w: 0.0,
99        },
100        row2: Vec4 {
101            x: 0.0,
102            y: 1.0,
103            z: 0.0,
104            w: 0.0,
105        },
106        row3: Vec4 {
107            x: 0.0,
108            y: 0.0,
109            z: 1.0,
110            w: 0.0,
111        },
112        row4: Vec4 {
113            x: 0.0,
114            y: 0.0,
115            z: 0.0,
116            w: 1.0,
117        },
118    }
119}
120
121/// Identity matrix. (A * Identity = A)
122pub const Matrix_Identity: Matrix = Matrix_IdentityValue();
123
124pub fn Matrix_Orthographic(
125    result: &mut Matrix,
126    left: c_float,
127    right: c_float,
128    top: c_float,
129    bottom: c_float,
130    zNear: c_float,
131    zFar: c_float,
132) {
133    /* Transposed, source https://msdn.microsoft.com/en-us/library/dd373965(v=vs.85).aspx */
134    *result = Matrix_Identity;
135
136    result.row1.x = 2.0 / (right - left);
137    result.row2.y = 2.0 / (top - bottom);
138    result.row3.z = -2.0 / (zFar - zNear);
139
140    result.row4.x = -(right + left) / (right - left);
141    result.row4.y = -(top + bottom) / (top - bottom);
142    result.row4.z = -(zFar + zNear) / (zFar - zNear);
143}
144
145pub fn Matrix_PerspectiveFieldOfView(
146    result: &mut Matrix,
147    fovy: c_float,
148    aspect: c_float,
149    zNear: c_float,
150    zFar: c_float,
151) {
152    let c = zNear * Tan_Simple(0.5 * fovy as c_double) as c_float;
153
154    /* Transposed, source https://msdn.microsoft.com/en-us/library/dd373537(v=vs.85).aspx */
155    /* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */
156    /* left = -c * aspect, right = c * aspect, bottom = -c, top = c */
157    /* Calculations are simplified because of left/right and top/bottom symmetry */
158    *result = Matrix_Identity;
159    result.row4.w = 0.0;
160
161    result.row1.x = zNear / (c * aspect);
162    result.row2.y = zNear / c;
163    result.row4.z = -(2.0 * zFar * zNear) / (zFar - zNear);
164    result.row3.z = -(zFar + zNear) / (zFar - zNear);
165    result.row3.w = -1.0;
166}
167
168pub fn Matrix_LookRot(result: &mut Matrix, pos: Vec3, rot: Vec2) {
169    let mut rotX = Matrix_Identity;
170    let mut rotY = Matrix_Identity;
171    let mut trans = Matrix_Identity;
172
173    unsafe {
174        Matrix_RotateX(&mut rotX, rot.y);
175        Matrix_RotateY(&mut rotY, rot.x);
176        Matrix_Translate(&mut trans, -pos.x, -pos.y, -pos.z);
177
178        Matrix_Mul(result, &rotY, &rotX);
179        Matrix_Mul(result, &trans, result);
180    }
181}